<!--
* @Description: 数据字典类别 - 表单
* @Author: DSY
* @Date: 2022-03-19 22:53:48
 * @LastEditors: DHL
 * @LastEditTime: 2022-07-15 12:25:14
-->
<template>
  <tw-dialog
    v-model="visible"
    :title="title"
    :loading="loading"
    width="600px"
    height="300px"
    @close="handleClose"
  >
    <el-form ref="dbFormRef" :model="dbForm" :rules="rules" label-width="90px">
      <el-form-item label="上级字典" prop="parentId">
        <el-input
          v-model="myData.parentName"
          :disabled="true"
          placeholder="请选择上级字典"
        ></el-input>
      </el-form-item>

      <el-form-item label="类别编码" prop="typeCode">
        <el-input v-model="dbForm.typeCode" clearable placeholder="请输入类别编码"></el-input>
      </el-form-item>

      <el-form-item label="类别名称" prop="typeName">
        <el-input v-model="dbForm.typeName" clearable placeholder="请输入类别名称"></el-input>
      </el-form-item>

      <el-form-item label="顺序号" prop="seqNum">
        <el-input-number v-model="dbForm.seqNum" clearable placeholder="请输入顺序号" />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="handleReset(true)">取 消</el-button>
      <el-button v-if="action === 'add'" type="warning" @click="handleSubmit(true)">
        提交并继续
      </el-button>
      <el-button v-if="action !== 'view'" type="primary" @click="handleSubmit(false)">
        提 交
      </el-button>
    </template>
  </tw-dialog>
</template>

<script lang="ts">
  export default { name: 'DataDic' }
</script>

<script setup lang="ts">
  import { computed, reactive, ref } from 'vue'
  import { assign, cloneDeep } from 'lodash-es'
  import { ElMessage } from 'element-plus'
  import { DataDicModel } from '/@/api/system/model/dataDicModel'
  import {
    apiDataDicGetNextSeqNumByTypeCode,
    apiDataDicSave,
    apiDataDicUpdateById
  } from '/@/api/system/dataDic'
  import { log } from '/@/utils/log'

  const emit = defineEmits<{
    (event: 'refreshTreeData'): void
  }>()

  //////////////////////////////////////////////////
  // 属性
  //////////////////////////////////////////////////
  const dbFormRef = ref()
  const loading = ref(true)

  /**
   * 表单操作标记
   */
  const action = ref('add')

  /**
   * 显示弹框
   */
  const visible = ref(false)

  /**
   * 标题
   */
  const title = computed(() => {
    let rtn = ''
    switch (action.value) {
      case 'add':
        rtn = '新增'
        break
      case 'edit':
        rtn = '编辑'
        break
      default:
        rtn = '查看'
        break
    }
    return rtn
  })

  /**
   * 公共
   */
  const myData = reactive({
    parentId: '',
    parentName: ''
  })

  //////////////////////////////////////////////////
  // 表单
  //////////////////////////////////////////////////

  const defaultForm = {
    typeCode: '', // 类别编码
    typeName: '', // 类别名称
    dataValue: '', // 字典值
    dataName: '', // 字典值名称
    type: '0', // 字典类型（0，分类；1，字典）
    zxbs: '0', // 注销标示 （0，未注销；1，注销）
    dataNameEn: '', // 字典英文名称
    seqNum: 0, // 顺序号
    smartCode: '', // 助记码
    tag1: '', // 扩展1
    tag2: '', // 扩展2
    tag3: '', // 扩展3
    parentId: '', // 父ID
    remark: '' // 描述
  }

  let dbForm = reactive<DataDicModel>(cloneDeep(defaultForm))

  //////////////////////////////////////////////////
  // 表单验证规则
  //////////////////////////////////////////////////

  /**
   * 表单验证规则
   */
  const rules = reactive({
    typeCode: [
      {
        required: true,
        message: '请输入类别编码',
        trigger: 'blur'
      }
    ],
    typeName: [
      {
        required: true,
        message: '请输入类别名称',
        trigger: 'blur'
      }
    ],
    seqNum: [
      {
        required: false,
        message: '请输入顺序号',
        trigger: 'blur'
      }
    ]
  })

  //////////////////////////////////////////////////
  // 函数
  //////////////////////////////////////////////////

  /**
   * 打开弹框
   */
  function handleOpen(actionParam: string, rowParam?: any, parentParams?: any) {
    visible.value = true
    loading.value = false
    action.value = actionParam

    assign(myData, parentParams)

    if (['edit', 'view'].indexOf(actionParam) > -1 && rowParam) {
      assign(dbForm, cloneDeep(rowParam), {
        id: rowParam.dicId
      })
    } else {
      handleSearchNextSeqNumByTypeCode()
    }
  }

  /**
   * 关闭弹框
   */
  function handleClose() {
    visible.value = false
  }

  /**
   * 提交表单
   */
  function handleSubmit(isContinue: boolean) {
    assign(dbForm, myData)
    dbFormRef.value.validate((valid: boolean) => {
      if (valid) {
        if (action.value === 'add') {
          addFun(isContinue)
        } else {
          editFun()
        }
      } else {
        log.warn('字典类别', '表单校验失败')
      }
    })
  }

  /**
   * 新增
   * @param isContinue 是否新增并继续
   */
  function addFun(isContinue: boolean) {
    loading.value = true
    apiDataDicSave(dbForm)
      .then((result) => {
        if (result?.success) {
          ElMessage.success(result.message)

          handleReset(!isContinue)
        } else {
          ElMessage.error(result?.message)
        }
      })
      .catch(() => {})
      .finally(() => {
        loading.value = false
      })
  }

  /**
   * 编辑
   * @returns
   */
  function editFun() {
    loading.value = true
    apiDataDicUpdateById(dbForm)
      .then((result) => {
        if (result?.success) {
          ElMessage.success(result.message)

          handleReset(true)
        } else {
          ElMessage.error(result?.message)
        }
      })
      .catch(() => {})
      .finally(() => {
        loading.value = false
      })
  }

  /**
   * 重置表单
   * @param isClosed 是否关闭弹框
   */
  function handleReset(isClosed: boolean) {
    assign(dbForm, cloneDeep(defaultForm))
    if (isClosed) {
      emit('refreshTreeData')
      visible.value = false
    } else {
      handleSearchNextSeqNumByTypeCode()
    }
  }

  /**
   * 查询下一个顺序号
   */
  function handleSearchNextSeqNumByTypeCode() {
    loading.value = true
    apiDataDicGetNextSeqNumByTypeCode(dbForm.typeCode ? dbForm.typeCode : '', '1')
      .then((result) => {
        if (result?.success) {
          dbForm.seqNum = result.data
        }
      })
      .finally(() => {
        loading.value = false
      })
  }

  defineExpose({ handleOpen })
</script>

<style scoped lang="scss"></style>
